import { constantRouterMap, asyncRouterMap } from '@/config/router.config'
import router from '@/router/index'
import { login, register, getUserDetail, getQrcode, getCaptcha } from '@/api/user'
import { defineStore } from "pinia"

const aToken = localStorage.getItem("access_token")
const rToken = localStorage.getItem("refresh_token")

export const useLayoutStore = defineStore("layout", {
    state: (): ILayout => ({
        menubar: {
            menuList: [],
        },
        userInfo: {
            name: "",
            desc: "",
            avatar: "",
            qq: "",
            vx: "",
            Role: {
                name: "",
                permission: [],
            }
        },
        status: {
            accessToken: aToken,
            refreshToken: rToken,
        },
        qrcode: {
            image: "",
            imageURL: "",
            ticket: "",
        },
        lastRoute: '',
        tags: [], // topNav 的所有小标签
        userRouters: [], // 当前用户所有可见菜单对应的路由
    }),
    getters: {
    },
    actions: {
        setQrcode(qrcode: IQrcode): void {
            this.qrcode = qrcode
        },
        logout(): void {
            this.status.accessToken = ""
            localStorage.clear()
            router.push({ path: '/login' })
        },
        login(loginParam: LoginParam) {
            return new Promise((resolve, reject) => {
                login(loginParam)
                    .then(res => {
                        localStorage.setItem("access_token", res.data.access_token)
                        localStorage.setItem("refresh_token", res.data.refresh_token)
                        this.status.accessToken = res.data.access_token
                        this.status.refreshToken = res.data.refresh_token
                        resolve(res)
                    })
                    .catch((error) => {
                        reject(error)
                    })
            })
        },
        register(registerParam: LoginParam) {
            return new Promise((resolve, reject) => {
                register(registerParam)
                    .then(res => {
                        resolve(res)
                    })
                    .catch((error) => {
                        reject(error)
                    })
            })
        },
        async getUserInfo(): Promise<void> {
            const res = await getUserDetail()
            this.userInfo = res.data
            localStorage.setItem("user_info", JSON.stringify(this.userInfo))
        },
        async generateRoutes() {
            await this.getUserInfo()
            const role = this.userInfo.Role
            const accessedRoutes = filterAsyncRouter(asyncRouterMap, role)
            accessedRoutes.forEach((r: any) => {
                router.addRoute(r)
            })
            // 将公开路由加进菜单
            // constantRouterMap.slice().reverse().forEach(r => { accessedRoutes.unshift(r) })
            this.menubar.menuList = accessedRoutes
            // 由于不知道如何公用公共组件，所以路由全作为 '/' 根路由的子路由来共享组件
            this.menubar.menuList = this.menubar.menuList[0].children
            // console.log(this.menubar.menuList)
        },
        async getCaptchaImage(): Promise<CaptchaImage> {
            return new Promise((resolve, reject) => {
                getCaptcha()
                    .then(res => {
                        resolve(res)
                    })
                    .catch(error => {
                        reject(error)
                    })
            })
        },
        async getQrcodeImage(): Promise<QrcodeImage> {
            return new Promise((resolve, reject) => {
                getQrcode()
                    .then(res => {
                        resolve(res)
                    })
                    .catch(error => {
                        reject(error)
                    })
            })
        }
    }
})


function hasPermission(permissions: any, route: any) {
    // 没有meta.permission的路由，默认放行
    if (route.meta && route.meta.permission) {
        // 有meta.permission的路由，根据服务器给出的roles.permissionlist决定是否放行
        let flag = false
        // 遍历服务器获取到的roles.permissions
        for (let p of permissions) {
            flag = route.meta.permission.includes(p)
            if (flag) {
                return true
            }
        }
        return false
    }
    return true
}

// routerMap中的route全部遍历，然后通过hasPermission()来将某一个route.meta.permission和roles.permissionList所有元素比较
// 比较相同则留下，不同就会filter掉
// 最后留下的便是所属权限对应的路由
function filterAsyncRouter(routerMap: any, roles: any) {
    const accessedRoutes = routerMap.filter((route: any) => {
        if (hasPermission(roles.permissions, route)) {
            if (route.children && route.children.length) {
                // 将filter后的路由重写回子路由
                route.children = filterAsyncRouter(route.children, roles)
                if (route.children.length == 0)
                    route.children = null
            }
            return true
        }
        return false
    })
    return accessedRoutes
}